//
// Created by 王筱童 on 2022/5/9.
//

#ifndef TINY_REDIS_SERVER_CMAKE_COMMAND_MANAGER_H
#define TINY_REDIS_SERVER_CMAKE_COMMAND_MANAGER_H
#include <unordered_map>
#include <string>
#include <tuple>
#include <vector>
#include <functional>

class redis_server;
class command_manager {
private:
    typedef std::vector<std::string> ret;
    typedef std::function<ret(command_manager*,std::vector<std::string>,std::uint64_t)> functor;
    using argc=std::size_t;
    using synable=bool;
    typedef std::tuple<functor,argc,synable> meta_type;

    constexpr static std::size_t functor_index=0;
    constexpr static std::size_t argc_index=1;
    constexpr static std::size_t synable_index=2;


    static std::unordered_map<std::string,meta_type> map_functor;
    class static_init{
    public:
        static_init();
    };

    static static_init init;

    std::vector<std::string> SET(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> GET(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> DEL(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> EXISTS(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> EXPRIE(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> PEXPRIE(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> HGET(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> HSET(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> HEXISTS(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> HDEL(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> HLEN(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> HGETALL(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> LLEN(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> LPUSH(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> LPOP(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> LRANGE(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> LINDEX(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> RPUSH(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> RPOP(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SADD(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SCARD(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SREM(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SCLR(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SGET(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> ZADD(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> ZCARD(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> ZRANGE(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> ZREM(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> ZGET(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> ZCLR(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> MULTI(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SAVEOF(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SENTI(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SELECT(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> SYNC(const std::vector<std::string>&, std::size_t);
    std::vector<std::string> PSENTI(const std::vector<std::string>&, std::size_t);

    redis_server *server;

public:
    command_manager(redis_server* _server);
    std::vector<std::string> exec_command(const std::string& command,const std::vector<std::string>&args,std::size_t);
};


#endif //TINY_REDIS_SERVER_CMAKE_COMMAND_MANAGER_H
